package com.rzw.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import javax.net.ssl.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;
import java.util.Map.Entry;

/**
 * http://blog.csdn.net/qq_22074635/article/details/51579119
 * 
 * @author Yibo Liu E-mail:iyibo1028@gmail.com
 *
 */
public class HttpUtil {
	private static final Logger logger = Logger.getLogger(HttpUtil.class.getName());

	public String getVersion() {
		HttpServletRequest request = ContextHolderUtils.getRequest();
		String version = request.getHeader("version");
		return version;
		
	}
	public static String sendGetRequest(String reqURL) {
		return HttpUtil.sendGetRequest(reqURL, null, "UTF-8");
	}

	public static String sendPostRequest1(String reqURL, Map<String, String> params, Map<String, Collection<String>> arrayParams) {
		return HttpUtil.sendPostRequest(reqURL, getPostParams(params,arrayParams), null, "UTF-8", "UTF-8");
	}

	public static String sendPostRequest(String reqURL, Map<String, String> params) {
		return HttpUtil.sendPostRequest(reqURL, getPostParams(params,null), null, "UTF-8", "UTF-8");
	}
	
	public static String sendPostRequest(String reqURL, String sendData) {
		return HttpUtil.sendPostRequest(reqURL, sendData, null, true);
	}
	
	
	public static String sendGetRequest(String reqURL, Map<String, String> headerMap) {
		return HttpUtil.sendGetRequest(reqURL, headerMap, "UTF-8");
	}
	
	/*public static String sendPostRequest(String reqURL, Map<String, String> params, Map<String, String> headerMap) {
		return HttpUtil.sendPostRequest(reqURL, params, headerMap, "UTF-8", "UTF-8");
	}*/
	
	public static String sendPostRequest(String reqURL, String sendData, Map<String, String> headerMap) {
		return HttpUtil.sendPostRequest(reqURL, sendData, headerMap, true);
	}

	/*
	 * public static CloseableHttpClient createSSLClientDefault() {
	 * 
	 * try {
	 * 
	 * SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null,
	 * new TrustStrategy() {
	 * 
	 * // 信任所有
	 * 
	 * @Override public boolean isTrusted(X509Certificate[] chain,
	 * 
	 * String authType) throws CertificateException {
	 * 
	 * return true;
	 * 
	 * }
	 * 
	 * }).build();
	 * 
	 * SSLConnectionSocketFactory sslsf = new
	 * SSLConnectionSocketFactory(sslContext); CloseableHttpClient httpClient =
	 * HttpClients.custom().setSSLSocketFactory(sslsf).build(); return
	 * httpClient;
	 * 
	 * } catch (KeyManagementException e) {
	 * 
	 * e.printStackTrace();
	 * 
	 * } catch (NoSuchAlgorithmException e) {
	 * 
	 * e.printStackTrace();
	 * 
	 * } catch (KeyStoreException e) {
	 * 
	 * e.printStackTrace();
	 * 
	 * }
	 * 
	 * return HttpClients.createDefault();
	 * 
	 * }
	 */

	/**
	 * 获取Https 请求客户端
	 * 
	 * @return
	 */
	public static CloseableHttpClient createSSLInsecureClient() {
		SSLContext sslcontext = createSSLContext();
		SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new HostnameVerifier() {

			@Override
			public boolean verify(String paramString, SSLSession paramSSLSession) {
				return true;
			}
		});
		CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
		return httpclient;
	}

	/**
	 * 获取初始化SslContext
	 * 
	 * @return
	 */
	private static SSLContext createSSLContext() {
		SSLContext sslcontext = null;
		try {
			sslcontext = SSLContext.getInstance("TLS");
			sslcontext.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new SecureRandom());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (KeyManagementException e) {
			e.printStackTrace();
		}
		return sslcontext;
	}

	/**
	 * 自定义静态私有类
	 */
	private static class TrustAnyTrustManager implements X509TrustManager {

		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		}

		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		}

		public X509Certificate[] getAcceptedIssuers() {
			return new X509Certificate[] {};
		}
	}

	/**
	 * 发送HTTP_GET请求
	 * 
	 * @see 该方法会自动关闭连接,释放资源
	 * @param requestURL
	 *            请求地址(含参数)
	 * @param decodeCharset
	 *            解码字符集,解析响应数据时用之,其为null时默认采用UTF-8解码
	 * @return 远程主机响应正文
	 * @throws IOException
	 */
	public static String sendGetRequest(String reqURL, Map<String, String> headerMap, String decodeCharset) {
		long responseLength = 0; // 响应长度
		String responseContent = null; // 响应内容
		// 创建默认的httpClient实例
		CloseableHttpClient httpClient = null;
        if (reqURL != null && reqURL.startsWith("https")) {
            httpClient = HttpUtil.createSSLInsecureClient();
        } else {
            httpClient = HttpClients.createDefault();
        }
		HttpGet httpGet = new HttpGet(reqURL); // 创建org.apache.http.client.methods.HttpGet

		if(headerMap != null) {
			for (Entry<String, String> entry : headerMap.entrySet()) {
				if(entry.getKey() != null && !"".equals(entry.getKey())) {
					httpGet.setHeader(entry.getKey(),entry.getValue());
				}
			}
		}
		CloseableHttpResponse response = null;
		try {
			response = httpClient.execute(httpGet); // 执行GET请求
			HttpEntity entity = response.getEntity(); // 获取响应实体
			if (null != entity) {
				responseLength = entity.getContentLength();
				responseContent = EntityUtils.toString(entity, decodeCharset == null ? "UTF-8" : decodeCharset);
				EntityUtils.consume(entity); // Consume response content

			}
			System.out.println("请求地址: " + httpGet.getURI());
			System.out.println("响应状态: " + response.getStatusLine());
			System.out.println("响应长度: " + responseLength);
			System.out.println("响应内容: " + responseContent);
		} catch (ClientProtocolException e) {
			logger.error("该异常通常是协议错误导致,比如构造HttpGet对象时传入的协议不对(将'http'写成'htp')或者服务器端返回的内容不符合HTTP协议要求等,堆栈信息如下", e);
		} catch (IOException e) {
			logger.error("该异常通常是网络原因引起的,如HTTP服务器未启动等,堆栈信息如下", e);
		} finally {
			try {
				if (response != null) {
					response.close();
				}
			} catch (IOException e) {
				logger.error(e);
			}
		}
		return responseContent;
	}

	/**
	 * 发送HTTP_POST请求
	 *
	 * @see 该方法会自动关闭连接,释放资源
	 * @see 当<code>isEncoder=true</code>时,其会自动对<code>sendData</code>中的[中文][|][
	 *      ]等特殊字符进行<code>URLEncoder.encode(string,encodeCharset)</code>
	 * @param reqURL
	 *            请求地址
	 * @param sendData
	 *            请求参数,若有多个参数则应拼接成param11=value11¶m22=value22¶m33=value33的形式后,
	 *            传入该参数中
	 * @param isEncoder
	 *            请求数据是否需要encodeCharset编码,true为需要
	 * @param encodeCharset
	 *            编码字符集,编码请求数据时用之,其为null时默认采用UTF-8解码
	 * @param decodeCharset
	 *            解码字符集,解析响应数据时用之,其为null时默认采用UTF-8解码
	 * @return 远程主机响应正文
	 */
	public static String sendPostRequest(String reqURL, String sendData, Map<String, String> headerMap, boolean isEncoder, String encodeCharset,
			String decodeCharset) {
		String responseContent = null;
		// 创建默认的httpClient实例
		CloseableHttpClient httpClient = null;
        if (reqURL != null && reqURL.startsWith("https")) {
            httpClient = HttpUtil.createSSLInsecureClient();
        } else {
            httpClient = HttpClients.createDefault();
        }

		HttpPost httpPost = new HttpPost(reqURL);
		if(headerMap != null) {
			for (Entry<String, String> entry : headerMap.entrySet()) {
				if(entry.getKey() != null && !"".equals(entry.getKey())) {
					httpPost.setHeader(entry.getKey(),entry.getValue());
				}
			}
		}
		// httpPost.setHeader(HTTP.CONTENT_TYPE,
		// "application/x-www-form-urlencoded; charset=UTF-8");
		CloseableHttpResponse response = null;
		try {
			httpPost.setHeader(HTTP.CONTENT_TYPE, "application/x-www-form-urlencoded");
			if (isEncoder) {
				List<NameValuePair> formParams = new ArrayList<NameValuePair>();
				for (String str : sendData.split("&")) {
					formParams.add(new BasicNameValuePair(str.substring(0, str.indexOf("=")), str.substring(str
							.indexOf("=") + 1)));
				}
				httpPost.setEntity(new StringEntity(URLEncodedUtils.format(formParams, encodeCharset == null ? "UTF-8"
						: encodeCharset)));
			} else {
				httpPost.setEntity(new StringEntity(sendData));
			}

			response = httpClient.execute(httpPost);
			HttpEntity entity = response.getEntity();
			if (null != entity) {
				responseContent = EntityUtils.toString(entity, decodeCharset == null ? "UTF-8" : decodeCharset);
				EntityUtils.consume(entity);
			}
		} catch (Exception e) {
			logger.error("与[" + reqURL + "]通信过程中发生异常,堆栈信息如下", e);
		} finally {
			try {
				if (response != null) {
					response.close();
				}
			} catch (IOException e) {
				logger.error(e);
			}
		}
		return responseContent;
	}

	/**
	 * 带参数的post方法
	 * @param url 请求地址
	 * @param param 请求参数
	 * @return
	 * @throws Exception
	 */
	public static String doPost(String url, Map<String, Object> param) throws Exception {
		CloseableHttpClient httpClient =HttpClients.createDefault();
		// 创建httpPost
		HttpPost http = new HttpPost(url);

		if (param != null) {
			List<NameValuePair> parameters = new ArrayList<NameValuePair>();
			Set<Entry<String, Object>> entrySet = param.entrySet();
			for (Entry<String, Object> entry : entrySet) {
				if(entry.getValue()!=null){
					parameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
				}
			}

			//设置参数
			http.setEntity(new UrlEncodedFormEntity(parameters, "utf-8"));
		}

		CloseableHttpResponse httpResponse = null;
		try {
			// 执行
			httpResponse = httpClient.execute(http);
			// 处理结果
			if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				String content = EntityUtils.toString(httpResponse.getEntity(), "utf-8");
				return "200";
			}
		} finally {
			if (httpResponse != null) {
				httpResponse.close();
			}
			httpClient.close();
		}
		return "OK";
	}




	/**
	 * 发送HTTP_POST请求
	 *
	 * @see 该方法会自动关闭连接,释放资源
	 * @see 该方法会自动对<code>params</code>中的[中文][|][ ]等特殊字符进行
	 *      <code>URLEncoder.encode(string,encodeCharset)</code>
	 * @param reqURL
	 *            请求地址
	 * @param params
	 *            请求参数
	 * @param encodeCharset
	 *            编码字符集,编码请求数据时用之,其为null时默认采用UTF-8解码
	 * @param decodeCharset
	 *            解码字符集,解析响应数据时用之,其为null时默认采用UTF-8解码
	 * @return 远程主机响应正文
	 */
	public static String sendPostRequest(String reqURL, List<NameValuePair> formParams, Map<String, String> headerMap, String encodeCharset,
			String decodeCharset) {
		String responseContent = null;
		// 创建默认的httpClient实例
		CloseableHttpClient httpClient = null;
        if (reqURL != null && reqURL.startsWith("https")) {
            httpClient = HttpUtil.createSSLInsecureClient();
        } else {
            httpClient = HttpClients.createDefault();
        }

		HttpPost httpPost = new HttpPost(reqURL);
		if(headerMap != null) {
			for (Entry<String, String> entry : headerMap.entrySet()) {
				if(entry.getKey() != null && !"".equals(entry.getKey())) {
					httpPost.setHeader(entry.getKey(),entry.getValue());
				}
			}
		}

		CloseableHttpResponse response = null;
		/*List<NameValuePair> formParams = new ArrayList<NameValuePair>(); // 创建参数队列
		if (params != null) {
			for (Map.Entry<String, String> entry : params.entrySet()) {
				formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
			}
		}*/
		try {
			httpPost.setEntity(new UrlEncodedFormEntity(formParams, encodeCharset == null ? "UTF-8" : encodeCharset));

			response = httpClient.execute(httpPost);
			HttpEntity entity = response.getEntity();
			if (null != entity) {
				responseContent = EntityUtils.toString(entity, decodeCharset == null ? "UTF-8" : decodeCharset);
				EntityUtils.consume(entity);
			}
		} catch (Exception e) {
			logger.error("与[" + reqURL + "]通信过程中发生异常,堆栈信息如下", e);
		} finally {
			try {
				if (response != null) {
					response.close();
				}
			} catch (IOException e) {
				logger.error(e);
			}
		}
		return responseContent;
	}

	/**
	 * 发送HTTP_POST请求
	 *
	 * @see 该方法为<code>sendPostRequest(String,String,boolean,String,String)</code>
	 *      的简化方法
	 * @see 该方法在对请求数据的编码和响应数据的解码时,所采用的字符集均为UTF-8
	 * @see 当<code>isEncoder=true</code>时,其会自动对<code>sendData</code>中的[中文][|][
	 *      ]等特殊字符进行<code>URLEncoder.encode(string,"UTF-8")</code>
	 * @param isEncoder
	 *            用于指明请求数据是否需要UTF-8编码,true为需要
	 */
	public static String sendPostRequest(String reqURL, String sendData, Map<String, String> headerMap, boolean isEncoder) {
		return sendPostRequest(reqURL, sendData, headerMap, isEncoder, null, null);
	}

	/**
	 * 使用百度短网址生成短网址
	 *
	 * param url
	 *            原始网址
	 * @return tinyurl 短网址
	 */
	@SuppressWarnings("unchecked")
	/*public static String getShortUrl(String url) {
		// url =
		// "http://www.kuaikuaizuche.com/activities/ownerrecommend/index.html?planId=7d62d3558a2947aa911cc1733887da1f";
		// String dwzParseUrl = "http://dwz.cn/query.php";
		String dwzCreateUrl = "http://dwz.cn/create.php";
		String tinyurl = url;
		try {
			Map<String, String> params = new HashMap<String, String>();
			params.put("url", url);
			String responseContent = HttpUtil.sendPostRequest(dwzCreateUrl, params);
			Map<String, String> paramsResp = null;
			if (responseContent != null) {
				paramsResp = (Map<String, String>) JSON.parse(responseContent);
			}
			if (paramsResp != null && paramsResp.containsKey("tinyurl")) {
				tinyurl = paramsResp.get("tinyurl");
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			logger.error(e);
		}
		return tinyurl;
	}*/

	/**
	 * 将map形式的请求参数, 转成字符串形式
	 * @param params
	 * @return
	 */
	public static String getUrlParams(HashMap<String, String> params) {
		if (params ==  null) return "";
		Set<String> keySet = params.keySet();
		StringBuilder urlParams = new StringBuilder();
		for (String key : keySet){
			urlParams.append("&"+key+"="+params.get(key));
		}
		urlParams.toString().substring(1);
		return urlParams.toString();
	}

	/**
	 * 获取POST的参数
	 *
	 * param httpPost
	 * param paramsMap
	 * throws Exception
	 */
	private static List<NameValuePair> getPostParams(Map<String, String> params,  Map<String, Collection<String>> arrayParams)
	{
		List<NameValuePair> nvps = new ArrayList<NameValuePair>();
		if (params != null && params.size() > 0) {
			Set<String> keySet = params.keySet();
			for (String key : keySet) {
				nvps.add(new BasicNameValuePair(key, params.get(key)));
			}
		}
		if(arrayParams != null) {
			for (Entry<String, Collection<String>> entry : arrayParams.entrySet()) {
				Iterator<String> iterator = entry.getValue().iterator();
				while(iterator.hasNext()) {
					nvps.add(new BasicNameValuePair(entry.getKey(), iterator.next()));
				}
			}
		}
		return nvps;
	}


	@SuppressWarnings({ "unused", "rawtypes" })
	public static void main(String[] args) {
		// TODO Auto-generated method stub
//		httpGet.setHeader(HttpHeaders.AUTHORIZATION, "Basic N2Q0MzFlNDJkZmE2YTZkNjkzYWMyZDA0OjVlOTg3YWM2ZDJlMDRkOTVhOWQ4ZjBkMQ==");
		
		/*String tinyurl = HttpUtil
				.getShortUrl("http://www.kuaikuaizuche.com/activities/ownerrecommend/index.html?planId=7d62d3558a2947aa911cc1733887da1f");
		System.out.println(tinyurl);*/
		
/*		Map<String, String> headerMap = new HashMap<String, String>();
		headerMap.put(HttpHeaders.AUTHORIZATION, "Basic N2Q0MzFlNDJkZmE2YTZkNjkzYWMyZDA0OjVlOTg3YWM2ZDJlMDRkOTVhOWQ4ZjBkMQ==");
		String result = HttpUtil.sendGetRequest("https://report.jpush.cn/v3/received?msg_ids=420939308", headerMap);
		System.out.println(result);*/
		String responseContent ="[{\"android_received\":1,\"ios_msg_received\":3,\"ios_apns_sent\":null,\"wp_mpns_sent\":null,\"msg_id\":1613113584},{\"android_received\":1,\"ios_msg_received\":null,\"ios_apns_sent\":null,\"wp_mpns_sent\":null,\"msg_id\":1613113584}]";
		JSONArray array = JSON.parseArray(responseContent);
		 List<Map> list = JSON.parseArray(responseContent, Map.class);
//		Object object = JSON.parse(responseContent);
		if(array != null && array.size() > 0) {
			JSONObject jSONObject = (JSONObject) array.get(0);
			System.out.println(jSONObject.toString());
			System.out.println(jSONObject.containsKey("android_received"));
			System.out.println(jSONObject.get("android_received"));
		}

/*		
		请求地址: https://report.jpush.cn/v3/received?msg_ids=1613113584
			响应状态: HTTP/1.1 200 OK
			响应长度: -1
			响应内容: [{"android_received":1,"ios_msg_received":null,"ios_apns_sent":null,"wp_mpns_sent":null,"msg_id":1613113584}]
			[{"android_received":1,"ios_msg_received":null,"ios_apns_sent":null,"wp_mpns_sent":null,"msg_id":1613113584}]*/
	}

}
